﻿using System.Numerics;
using WaveSim.Core.Equations;

namespace WaveSim.Core.Methods.ODE
{
    [MethodODE("Runge 4", Description = "A Runge-Kutta method of 4th degree")]
    public class Runge4 : IMethodODE
    {
        Complex[] yt, k1, k2, k3, k4;

        private void init(int n)
        {
            if (yt == null)
            {
                yt = new Complex[n];
                k1 = new Complex[n];
                k2 = new Complex[n];
                k3 = new Complex[n];
                k4 = new Complex[n];
            }
        }

        public void Solve(double x, double h, Complex[] y, IEquation f, int iteration = 0)
        {
            init(y.Length);
            for (int i = 0; i < y.Length; i++)
            {
                k1[i] = h * f.Get(i, x, y);
                yt[i] = y[i] + 0.5 * k1[i];
            }
            for (int i = 0; i < y.Length; i++)
            {
                k2[i] = h * f.Get(i, x + h * 0.5, yt);
                yt[i] = y[i] + 0.5 * k2[i];
            }
            for (int i = 0; i < y.Length; i++)
            {
                k3[i] = h * f.Get(i, x + h * 0.5, yt);
                yt[i] = y[i] + k3[i];
            }
            for (int i = 0; i < y.Length; i++)
            {
                k4[i] = h * f.Get(i, x + h, yt);
            }
            for (int i = 0; i < y.Length; i++)
            {
                y[i] += (k1[i] + 2.0 * k2[i] + 2.0 * k3[i] + k4[i]) / 6;
            }
        }
    }
}
